import { computed, defineComponent, ref } from "vue";
import { InfoLineProps } from "@/components/info-line/src/types";
import InfoLineRender from "./Render";
import TitanPreview from "./Preview.vue";

export default defineComponent({
  name: "TitanInfoLine",
  props: InfoLineProps,
  emits: ["popup-visible-change"],
  setup(props, { emit }) {
    const visible = ref<boolean>(false);
    // render function
    const setRenderFunc = (data: any) => {
      if (props.lineData.render) {
        const renderProps = {
          data,
          render: props.lineData.render,
        };
        return <InfoLineRender {...renderProps}></InfoLineRender>;
      }
      return props.isEllipsis ? (
        <a-tooltip content={data}>
          <span>{data}</span>
        </a-tooltip>
      ) : (
        <span>{data}</span>
      );
    };

    // 单值多值判断
    const isMultipleValue = computed(() => {
      return Array.isArray(props.lineData.value);
    });

    // label width
    const calcLabelWidth = computed(() => {
      if (!props.lineData.label || props.lineData.labelWidth === 0) {
        return 0;
      }
      if (props.lineData.labelWidth) {
        return props.lineData.labelWidth + "px";
      }
      if (props.lineData.labelIcon) {
        return "16px";
      }
      if (!props.labelWidth) {
        return "70px";
      }
      return props.labelWidth + "px";
    });

    const spanWidth = computed(() => {
      if (props.lineData.span === 24 || !props.lineData.span) return "100%";
      return `calc(100% / 24 * ${props.lineData.span})`;
    });

    const show = computed(() => {
      if (typeof props.lineData.value === "string" && props.lineData.value) {
        return true;
      }
      if (typeof props.lineData.value === "number") {
        return true;
      }
      return !!(props.lineData.value instanceof Array && props.lineData.value.length);
    });

    const lineLimit = computed(() => {
      return props.lineData.limit || props.limit;
    });

    const handlePopoverChange = (visible: boolean, index = 0) => {
      const value =
        props.lineData.value instanceof Array ? (props.lineData.value.length ? props.lineData.value[index] : "") : props.lineData.value || "";
      emit("popup-visible-change", visible, value);
    };

    const popoverOptions = {
      disabled: !props.lineData.popover,
    };
    Object.assign(popoverOptions, props.lineData.popover || {});

    return () => {
      // label render
      const labelRender =
        (props.lineData.label || props.lineData.labelIcon) && props.lineData.labelWidth !== 0 ? (
          <div
            class={`titan-info-line_label ${props.labelPosition === "right" ? "align-right" : ""} ${props.lineData.labelIcon ? "icon-label" : ""}`}
            style={`flex: 0 0 ${calcLabelWidth.value}`}
          >
            {props.lineData.labelIcon ? (
              <a-tooltip
                content={props.lineData.label}
                disabled={!props.lineData.label}
              >
                <svg-icon
                  name={props.lineData.labelIcon}
                  size={16}
                />
              </a-tooltip>
            ) : (
              <span>{props.lineData.label + "："}</span>
            )}
          </div>
        ) : null;

      // main render
      let valueRender = null;
      const className = ["titan-info-line_value"];
      if (props.isEllipsis) {
        className.push("ellipsis");
      }
      if (isMultipleValue.value) {
        const _value = lineLimit.value > 0 ? (props.lineData.value as any[]).slice(0, lineLimit.value) : (props.lineData.value as any[]);
        if (lineLimit.value <= 0 || lineLimit.value > 1) {
          className.push("is-background");
        }
        valueRender = show.value ? (
          _value.map((item, index) => {
            return (
              <a-popover
                v-slots={props.lineData.popoverSlots || {}}
                {...popoverOptions}
                onPopupVisibleChange={(visible: boolean) => handlePopoverChange(visible, index)}
              >
                <div class={className.join(" ")}>{setRenderFunc(item)}</div>
              </a-popover>
            );
          })
        ) : (
          <div class={className.join(" ")}>暂无数据</div>
        );
      } else {
        valueRender = show.value ? (
          <a-popover
            v-slots={props.lineData.popoverSlots || {}}
            {...popoverOptions}
            onPopupVisibleChange={(visible: boolean) => handlePopoverChange(visible)}
          >
            <div class={className.join(" ")}>{setRenderFunc(props.lineData.value)}</div>
          </a-popover>
        ) : (
          <div class={className.join(" ")}>暂无数据</div>
        );
      }

      // overflow render
      let overflowRender = null;
      const handleClick = (e: Event) => {
        e.stopPropagation();
        visible.value = true;
      };
      if (isMultipleValue.value && lineLimit.value > 0 && (props.lineData.value as any[]).length > lineLimit.value) {
        overflowRender = (
          <div
            class={`show-more titan-info-line_value ${props.lineData.limitType === "text" ? "fs-12" : ""}`}
            onClick={handleClick}
          >
            {props.lineData.limitType === "text"
              ? `查看${(props.lineData.value as any[]).length - (lineLimit.value || 1)}个未显示${props.lineData.label}`
              : `+${(props.lineData.value as any[]).length - (lineLimit.value || 1)}`}
          </div>
        );
      }

      return (
        <div
          class="titan-info-line"
          style={`width: ${spanWidth.value}`}
        >
          {labelRender}

          <div
            class="titan-info-line_main"
            style={`max-width: calc(100% - ${calcLabelWidth.value} - 10px)`}
          >
            {valueRender && valueRender}
            {overflowRender && overflowRender}
          </div>

          {visible.value && (
            <TitanPreview
              v-model:visible={visible.value}
              data={props.lineData}
              size={props.pageSize}
              pagination={props.pagination}
            />
          )}
        </div>
      );
    };
  },
});
